package com.ruoyi.web.controller.subsidy;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.utils.poi.ExcelUtilNew;
import com.ruoyi.common.utils.uuid.DynamicExcelExporter;
import com.ruoyi.subsidy.domain.bo.*;
import com.ruoyi.subsidy.domain.vo.SysPlantingPriceVo;
import com.ruoyi.subsidy.service.*;
import com.ruoyi.system.service.ISysOssService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.commonService.SmsResponse;
import com.ruoyi.subsidy.domain.vo.SysStrativeAreaVo;
import com.ruoyi.subsidy.service.ISysSubsidyPlantingService;
import com.ruoyi.system.domain.bo.*;
import com.ruoyi.system.domain.vo.SysOssVo;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.DigestUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 农业补贴申请
 *
 * @author nbacheng
 * @date 2025-08-07
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/subsidy/subsidyApplicationPlanting")
@SaIgnore
public class SysSubsidyApplicationPlantingController extends BaseController {

    //private final iSysSubsidyPlantingService iSysSubsidyPlantingService;
    private static final Logger logger = LoggerFactory.getLogger(SysSubsidyApplicationPlantingController.class);


    private final ISysSubsidyPlantingService iSysSubsidyPlantingService;

    private final ISysStrativeAreaService iSysStrativeAreaService;

    private final ISysPlantingTownttachService iSysPlantingTownttachService;

    private final ISysOssService iSysOssService;

    private final ISysPlantingPriceService iSysPlantingPriceService;

    //192.150.254.243:45180/

    // @Value("${sms.third-party.url}")
    private final static String apiUrl = "http://jixi.hlwapi.cegn.cn:45180/outsidegateway/d3d38d8d/formSetting/getIdentityInfo";

    private final static String apiUrlneiwang = "http://192.150.254.243:45180/outsidegateway/d3d38d8d/formSetting/getIdentityInfo";

    // @Value("${sms.third-party.url}")
    private final static String apiUrlms = "http://192.150.254.243:45180/outsidegateway/2c40j040sb40n929/gw/v3/sfrz/api/userVerify/sendVerification";

    private final static String apiUrlneiwangms = "http://jixi.zwapi.hlj.c egn.cn:45180/outsidegateway/2c40j040sb40n929/gw/v3/sfrz/api/userVerify/sendVerification";

    @Value("${jx.sign.url}")
    private  String apiUrlyin;

    private final static String apiUrlneiyin = "http://jixi.zwapi.hlj.cegn.cn:45180/outsidegateway/20574369/ESS/sealAutoPdfZF";

    private final static String AppKey = "c906baa0a03a40ccb445a634dd340d75";

    // @Value("${sms.third-party.app-secret}")
    private final static String AppSecret = "97ac3144d326302dde649625d510b0d7";

    private final ObjectMapper xmlMapper = new XmlMapper();

   // private DataFormatter formatter = new DataFormatter();


    /**
     * 查询农业补贴申请列表
     */
    // @SaCheckPermission("subsidy:subsidyApplication:list")

    // @SaCheckPermission("subsidy:subsidyApplication:list")
    @GetMapping("/historyOne")
    public SysSubsidyPlantingBo historyOne(SysSubsidyPlantingBo bo) {
        SysSubsidyPlantingBo bores=new SysSubsidyPlantingBo();
        List<SysSubsidyPlantingBo> list=iSysSubsidyPlantingService.queryList(bo);
        if (CollectionUtils.isNotEmpty(list)){
            bores=list.get(0);
        }
        return bores;
    }

    @PostMapping("/subsidyImport")
    public String importSubsidyData(@RequestParam("file") MultipartFile file,SysSubsidyPlantingBo bo) {
        try {
            Workbook workbook = new XSSFWorkbook(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);

            List<String> successList = new ArrayList<>();
            List<String> errorList = new ArrayList<>();

            for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 从第二行开始读取
                Row row = sheet.getRow(i);
                if (row == null) continue;

                try {
                    // 读取第2、3、4、7列数据（索引从0开始）
                    String appyBy = getCellValue(row, 1); // 第2列：收款人全称
                    String idCard = getCellValue(row, 2); // 第3列：身份证号
                    String phone = getCellValue(row, 3);  // 第4列：手机号码
                    String yumiareaAmountStr="0";
                    String dadouareaAmount="0";
                    String daoguheareaAmount="0";
                    if(bo.getYumiareaAmount() !=null) {
                         yumiareaAmountStr = getCellValue(row, 6); // 第7列：亩数
                    }
                    if(bo.getDadouareaAmount() !=null) {
                         dadouareaAmount = getCellValue(row, 6); // 第7列：亩数
                    }
                    if(bo.getDaoguheareaAmount() !=null) {
                         daoguheareaAmount = getCellValue(row, 6); // 第7列：亩数
                    }

                    // 解析身份证信息
                    SysSubsidyPlantingBo boo = new SysSubsidyPlantingBo();
                    boo.setAppyBy(appyBy);
                    boo.setIdCard(idCard);
                    boo.setPhone(phone);
                    boo.setVillageName(bo.getVillageName());
                    boo.setNodeName(bo.getVillageName());
                    boo.setTownName(bo.getTownName());
                    boo.setStraName(bo.getStraName());
                    boo.setIdCardAddr(bo.getIdCardAddr());
                    boo.setAppType(bo.getAppType());
                    boo.setOftenAddr(bo.getOftenAddr());
                    boo.setSubmitBy(bo.getSubmitBy());
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    Date submitDate = sdf.parse("2025-8-15");
                    boo.setSubmitDate(submitDate);
                    boo.setYear(bo.getYear());
                    // 解析亩数
                    try {

                        boo.setYumiareaAmount(new BigDecimal(yumiareaAmountStr));
                        boo.setDadouareaAmount(new BigDecimal(dadouareaAmount));
                        boo.setDaoguheareaAmount(new BigDecimal(daoguheareaAmount));
                    } catch (NumberFormatException e) {
                        errorList.add("第" + (i+1) + "行：亩数格式不正确");
                        continue;
                    }

                    // 解析身份证性别和年龄
                    parseIdCardInfo(idCard, boo);

                    // 调用插入方法
                    SysSubsidyPlantingBo querybo = new SysSubsidyPlantingBo();
                    querybo.setIdCard(idCard);
                    querybo.setVillageName(bo.getVillageName());
                    querybo.setAppyBy(appyBy);
                    SysSubsidyPlantingBo resultbo=historyOne(querybo);
                    String orderNum="";
                    if(resultbo.getId() !=null){
                        if(resultbo.getYumiareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getYumiareaAmount()==null) {
                            resultbo.setYumiareaAmount(boo.getYumiareaAmount());
                        }
                        if(resultbo.getDaoguheareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getDaoguheareaAmount()==null) {
                            resultbo.setDaoguheareaAmount(boo.getDaoguheareaAmount());
                        }
                        if(resultbo.getDadouareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getDadouareaAmount()==null) {
                            resultbo.setDadouareaAmount(boo.getDadouareaAmount());
                        }
                        iSysSubsidyPlantingService.updateByBo(resultbo);
                    }else {
                         orderNum = iSysSubsidyPlantingService.insertByBo(boo);
                    }
                    //iSysSubsidyPlantingService.updateByBo(bo)
                    //iSysSubsidyPlantingService.insertByBo(bo)
                    successList.add("第" + (i+1) + "行导入成功，订单号：" + orderNum);

                } catch (Exception e) {
                    errorList.add("第" + (i+1) + "行导入失败：" + e.getMessage());
                }
            }

            workbook.close();

            return "导入结果：成功" + successList.size() + "条，失败" + errorList.size() + "条\n" +
                "成功记录：" + successList + "\n" +
                "失败记录：" + errorList.size();

        } catch (IOException e) {
            return "文件读取失败：" + e.getMessage();
        }
    }

    @PostMapping("/subsidyImportgendidili")
    public String importSubsidyDatagendidili(@RequestParam("file") MultipartFile file,SysSubsidyPlantingBo bo) {
        try {
            Workbook workbook = new XSSFWorkbook(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);

            List<String> successList = new ArrayList<>();
            List<String> errorList = new ArrayList<>();

            for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 从第二行开始读取
                Row row = sheet.getRow(i);
                if (row == null) continue;

                try {
                    // 读取第2、3、4、7列数据（索引从0开始）
                    String appyBy = getCellValue(row, 1); // 第2列：收款人全称
                    String idCard = getCellValue(row, 2); // 第3列：身份证号
                    String phone = getCellValue(row, 3);  // 第4列：手机号码
                    String bankCard = getCellValue(row, 6);  // 第4列：手机号码
                    String yumiareaAmountStr="0";
                    String dadouareaAmount="0";
                    String daoguheareaAmount="0";
                    String farmlandraeaAmount="0";
                    if(bo.getYumiareaAmount() !=null) {
                        yumiareaAmountStr = getCellValue(row, 6); // 第7列：亩数
                    }
                    if(bo.getDadouareaAmount() !=null) {
                        dadouareaAmount = getCellValue(row, 6); // 第7列：亩数
                    }
                    if(bo.getDaoguheareaAmount() !=null) {
                        daoguheareaAmount = getCellValue(row, 6); // 第7列：亩数
                    }
                    if(bo.getFarmlandareaAmount() !=null) {
                        farmlandraeaAmount = getCellValue(row, 13); // 第7列：亩数
                    }

                    // 解析身份证信息
                    SysSubsidyPlantingBo boo = new SysSubsidyPlantingBo();
                    boo.setAppyBy(appyBy);
                    boo.setIdCard(idCard);
                    boo.setPhone(phone);
                    boo.setBankCard(bankCard);
                    boo.setVillageName(bo.getVillageName());
                    boo.setNodeName(bo.getVillageName());
                    boo.setTownName(bo.getTownName());
                    boo.setStraName(bo.getStraName());
                    boo.setIdCardAddr(bo.getIdCardAddr());
                    boo.setAppType(bo.getAppType());
                    boo.setOftenAddr(bo.getOftenAddr());
                    boo.setSubmitBy(bo.getSubmitBy());
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    Date submitDate = sdf.parse("2025-8-15");
                    boo.setSubmitDate(submitDate);
                    boo.setYear(bo.getYear());
                    // 解析亩数
                    try {

                        boo.setYumiareaAmount(new BigDecimal(yumiareaAmountStr));
                        boo.setDadouareaAmount(new BigDecimal(dadouareaAmount));
                        boo.setDaoguheareaAmount(new BigDecimal(daoguheareaAmount));
                        boo.setFarmlandareaAmount(new BigDecimal(farmlandraeaAmount));
                    } catch (NumberFormatException e) {
                        errorList.add("第" + (i+1) + "行：亩数格式不正确");
                        continue;
                    }

                    // 解析身份证性别和年龄
                    parseIdCardInfo(idCard, boo);

                    // 调用插入方法
                    SysSubsidyPlantingBo querybo = new SysSubsidyPlantingBo();
                    querybo.setIdCard(idCard);
                    querybo.setVillageName(bo.getVillageName());
                    querybo.setAppyBy(appyBy);
                    querybo.setAppType(bo.getAppType());
                    SysSubsidyPlantingBo resultbo=historyOne(querybo);
                    String orderNum="";
                    if(resultbo.getId() !=null){
                        if(resultbo.getYumiareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getYumiareaAmount()==null) {
                            resultbo.setYumiareaAmount(boo.getYumiareaAmount());
                        }
                        if(resultbo.getDaoguheareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getDaoguheareaAmount()==null) {
                            resultbo.setDaoguheareaAmount(boo.getDaoguheareaAmount());
                        }
                        if(resultbo.getDadouareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getDadouareaAmount()==null) {
                            resultbo.setDadouareaAmount(boo.getDadouareaAmount());
                        }
                        if("耕地地力补贴".equals(resultbo.getAppType())){
                            resultbo.setFarmlandareaAmount(new BigDecimal(farmlandraeaAmount).add(resultbo.getFarmlandareaAmount()));
                        }
                        iSysSubsidyPlantingService.updateByBo(resultbo);
                    }else {
                        orderNum = iSysSubsidyPlantingService.insertByBo(boo);
                    }
                    //iSysSubsidyPlantingService.updateByBo(bo)
                    //iSysSubsidyPlantingService.insertByBo(bo)
                    successList.add("第" + (i+1) + "行导入成功，订单号：" + orderNum);

                } catch (Exception e) {
                    errorList.add("第" + (i+1) + "行导入失败：" + e.getMessage());
                }
            }

            workbook.close();

            return "导入结果：成功" + successList.size() + "条，失败" + errorList.size() + "条\n" +
                "成功记录：" + successList + "\n" +
                "失败记录：" + errorList.size();

        } catch (IOException e) {
            return "文件读取失败：" + e.getMessage();
        }
    }

    @PostMapping("/subsidyImportgendidiliyes")
    public String importSubsidyDatagendidiliyes(@RequestParam("file") MultipartFile file,SysSubsidyPlantingBo bo) {
        try {
            Workbook workbook = new XSSFWorkbook(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);

            List<String> successList = new ArrayList<>();
            List<String> errorList = new ArrayList<>();

            for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 从第二行开始读取
                Row row = sheet.getRow(i);
                if (row == null) continue;

                try {
                    // 读取第2、3、4、7列数据（索引从0开始）
                    String appyBy = getCellValue(row, 6); // 第2列：收款人全称
                    String idCard = getCellValue(row, 7); // 第3列：身份证号
                    String villageName = getCellValue(row, 8); // 第2列：收款人全称
                    String townname = getCellValue(row, 2); // 第3列：身份证号

                   // String phone = getCellValue(row, 3);  // 第4列：手机号码
                   // String bankCard = getCellValue(row, 6);  // 第4列：手机号码
                    String yumiareaAmountStr="0";
                    String dadouareaAmount="0";
                    String daoguheareaAmount="0";
                    String farmlandraeaAmount="0";
                    if(bo.getYumiareaAmount() !=null) {
                        yumiareaAmountStr = getCellValue(row, 6); // 第7列：亩数
                    }
                    if(bo.getDadouareaAmount() !=null) {
                        dadouareaAmount = getCellValue(row, 6); // 第7列：亩数
                    }
                    if(bo.getDaoguheareaAmount() !=null) {
                        daoguheareaAmount = getCellValue(row, 6); // 第7列：亩数
                    }
                    if(bo.getFarmlandareaAmount() !=null) {
                        farmlandraeaAmount = getCellValue(row, 5); // 第7列：亩数
                    }

                    // 解析身份证信息
                    SysSubsidyPlantingBo boo = new SysSubsidyPlantingBo();
                    boo.setAppyBy(appyBy);
                    boo.setIdCard(idCard);
                  //  boo.setPhone(phone);
                   // boo.setBankCard(bankCard);
                    boo.setVillageName(villageName);
                    boo.setNodeName(villageName);
                    boo.setTownName(townname);
                    boo.setStraName(bo.getStraName());
                    boo.setIdCardAddr(villageName);
                    boo.setAppType(bo.getAppType());
                    boo.setOftenAddr(villageName);
                    boo.setSubmitBy(villageName);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    Date submitDate = sdf.parse("2024-8-15");
                    boo.setSubmitDate(submitDate);
                    boo.setYear(bo.getYear());
                    // 解析亩数
                    try {

                        boo.setYumiareaAmount(new BigDecimal(yumiareaAmountStr));
                        boo.setDadouareaAmount(new BigDecimal(dadouareaAmount));
                        boo.setDaoguheareaAmount(new BigDecimal(daoguheareaAmount));
                        boo.setFarmlandareaAmount(new BigDecimal(farmlandraeaAmount));
                    } catch (NumberFormatException e) {
                        errorList.add("第" + (i+1) + "行：亩数格式不正确");
                        continue;
                    }

                    // 解析身份证性别和年龄
                    parseIdCardInfo(idCard, boo);

                    // 调用插入方法
                    SysSubsidyPlantingBo querybo = new SysSubsidyPlantingBo();
                    querybo.setIdCard(idCard);
                    querybo.setVillageName(bo.getVillageName());
                    querybo.setAppyBy(appyBy);
                    querybo.setAppType(bo.getAppType());
                    SysSubsidyPlantingBo resultbo=historyOne(querybo);
                    String orderNum="";
                    if(resultbo.getId() !=null){
                        if(resultbo.getYumiareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getYumiareaAmount()==null) {
                            resultbo.setYumiareaAmount(boo.getYumiareaAmount());
                        }
                        if(resultbo.getDaoguheareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getDaoguheareaAmount()==null) {
                            resultbo.setDaoguheareaAmount(boo.getDaoguheareaAmount());
                        }
                        if(resultbo.getDadouareaAmount().compareTo(BigDecimal.ZERO)==0 || resultbo.getDadouareaAmount()==null) {
                            resultbo.setDadouareaAmount(boo.getDadouareaAmount());
                        }
                        if("耕地地力补贴".equals(resultbo.getAppType())){
                            resultbo.setFarmlandareaAmount(new BigDecimal(farmlandraeaAmount).add(resultbo.getFarmlandareaAmount()));
                        }
                        iSysSubsidyPlantingService.updateByBo(resultbo);
                    }else {
                        orderNum = iSysSubsidyPlantingService.insertByBo(boo);
                    }
                    //iSysSubsidyPlantingService.updateByBo(bo)
                    //iSysSubsidyPlantingService.insertByBo(bo)
                    successList.add("第" + (i+1) + "行导入成功，订单号：" + orderNum);

                } catch (Exception e) {
                    errorList.add("第" + (i+1) + "行导入失败：" + e.getMessage());
                }
            }

            workbook.close();

            return "导入结果：成功" + successList.size() + "条，失败" + errorList.size() + "条\n" +
                "成功记录：" + successList + "\n" +
                "失败记录：" + errorList.size();

        } catch (IOException e) {
            return "文件读取失败：" + e.getMessage();
        }
    }




    private String getCellValue(Row row, int columnIndex) {
        Cell cell = row.getCell(columnIndex);
        DataFormatter formatter = new DataFormatter();
        /*if (cell == null) {
            return "";
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                return String.valueOf((int)cell.getNumericCellValue());
            default:
                return "";
        }*/
        return formatter.formatCellValue(cell);
    }

    private void parseIdCardInfo(String idCard, SysSubsidyPlantingBo bo) {
        if (idCard == null || idCard.length() < 17) {
            bo.setSex("未知");
            bo.setAge("0");
            return;
        }

        // 解析性别：身份证第17位，奇数男，偶数女
        char sexChar = idCard.charAt(16);
        bo.setSex(Character.isDigit(sexChar) && Integer.parseInt(String.valueOf(sexChar)) % 2 == 1 ? "男" : "女");

        // 解析年龄：身份证第7-10位为出生年份
        int year = Integer.parseInt(idCard.substring(6, 10));
        int currentYear = Calendar.getInstance().get(Calendar.YEAR);
        bo.setAge(String.valueOf(currentYear - year));
    }



    /**
     * 查询农业补贴申请列表
     */
    // @SaCheckPermission("subsidy:subsidyApplication:list")
    @GetMapping("/listDadou")
    public List<String> list(SysSubsidyPlantingBo bo) {
        return iSysSubsidyPlantingService.queryDadouType(bo);
    }

    @GetMapping("/list")
    public TableDataInfo<SysSubsidyPlantingBo> list(SysSubsidyPlantingBo bo, PageQuery pageQuery) {
        return iSysSubsidyPlantingService.queryPageList(bo, pageQuery);
    }


    /**
     * 申
     * 导出农业补贴申请列表
     */
    // @SaCheckPermission("subsidy:subsidyApplication:export")
    @Log(title = "补贴请", businessType = BusinessType.EXPORT)
    @PostMapping("/export1")
    public void export1(SysSubsidyPlantingBo bo, HttpServletResponse response) throws IOException {

        List<SysSubsidyPlantingBo> dataList = iSysSubsidyPlantingService.queryList(bo);
        Map<String, String> conditionParams = new HashMap<>();
        conditionParams.put("excelTypeDidao", bo.getExcelTypeDidao());
        Map<String, Object> res = new HashMap<>();
        List<SysSubsidyPlantingBo> sysvo = new ArrayList<>();
        for (SysSubsidyPlantingBo boo : dataList) {
            res = DynamicExcelExporter.processToMap(boo, conditionParams);
            ObjectMapper mapper = new ObjectMapper();
            SysSubsidyPlantingBo vo = mapper.convertValue(res, SysSubsidyPlantingBo.class);
            sysvo.add(vo);
        }

        // 执行导出
        //ExcelUtil<SysSubsidyPlantingBo> util = new ExcelUtil<SysSubsidyPlantingBo>(SysSubsidyPlantingBo.class);
        // util.exportExcel(response, list, "岗位数据");

        ExcelUtil.exportExcel(sysvo, "补贴申请", SysSubsidyPlantingBo.class, response);
    }

    @PostMapping("/export")
    public void export(SysSubsidyPlantingBo bo, HttpServletResponse response) throws IOException {
        PageQuery pageQuery=new PageQuery();
        pageQuery.setPageNum(1);
        pageQuery.setPageSize(500000);
        //iSysSubsidyPlantingService.queryPageList(bo, pageQuery).getRows();
        List<SysSubsidyPlantingBo> dataList = iSysSubsidyPlantingService.queryPageList(bo, pageQuery).getRows();

        ExcelUtilNew<SysSubsidyPlantingBo> util = new ExcelUtilNew<SysSubsidyPlantingBo>(SysSubsidyPlantingBo.class);
        if ("玉米补贴".equals(bo.getExportType())) {
            // 不显示用户ID（单个）
            util.hideColumn("dadouareaAmount","dadouareaAmountPri","daogudixiaareaAmount","daogudixiaareaAmountPri",
                "daogudibiareaAmount","daogudibiareaAmountPri","areaAmountdouGaoyou","areaAmountdouGaoyouPri",
                "areaAmountdouGaodanbai","areaAmountdouGaodanbaiPri","farmlandareaAmount","farmlandareaAmountPri");
        }
        if ("大豆补贴".equals(bo.getExportType())) {
            // 不显示用户ID（单个）
            util.hideColumn("yumiareaAmount","yumiareaAmountPri","daogudixiaareaAmount","daogudixiaareaAmountPri",
                "daogudibiareaAmount","daogudibiareaAmountPri","areaAmountdouGaoyou","areaAmountdouGaoyouPri",
                "areaAmountdouGaodanbai","areaAmountdouGaodanbaiPri","farmlandareaAmount","farmlandareaAmountPri");
        }
        if ("稻谷补贴".equals(bo.getExportType())) {
            // 不显示用户ID（单个）
            util.hideColumn("dadouareaAmount","dadouareaAmountPri","yumiareaAmount","yumiareaAmountPri"
               ,"areaAmountdouGaoyou","areaAmountdouGaoyouPri","areaAmountdouGaodanbai","areaAmountdouGaodanbaiPri",
                "farmlandareaAmount","farmlandareaAmountPri");
        }
        if ("高油大豆补贴".equals(bo.getExportType())) {
            // 不显示用户ID（单个）
            util.hideColumn("dadouareaAmount","dadouareaAmountPri","daogudixiaareaAmount","daogudixiaareaAmountPri",
                "daogudibiareaAmount","daogudibiareaAmountPri","areaAmountdouGaodanbai","areaAmountdouGaodanbaiPri",
                "farmlandareaAmount","farmlandareaAmountPri","yumiareaAmount","yumiareaAmountPri");
        }
        if ("高蛋白大豆补贴".equals(bo.getExportType())) {
            // 不显示用户ID（单个）
            util.hideColumn("dadouareaAmount","dadouareaAmountPri","daogudixiaareaAmount","daogudixiaareaAmountPri",
                "daogudibiareaAmount","daogudibiareaAmountPri","areaAmountdouGaoyou","areaAmountdouGaoyouPri",
                "farmlandareaAmount","farmlandareaAmountPri","yumiareaAmount","yumiareaAmountPri");
        }
        if ("耕地地力补贴".equals(bo.getExportType())) {
            // 不显示用户ID（单个）
            util.hideColumn("dadouareaAmount","dadouareaAmountPri","daogudixiaareaAmount","daogudixiaareaAmountPri",
                "daogudibiareaAmount","daogudibiareaAmountPri","areaAmountdouGaoyou","areaAmountdouGaoyouPri",
                "areaAmountdouGaodanbai","areaAmountdouGaodanbaiPri","yumiareaAmount","yumiareaAmountPri");
        }

        util.exportExcel(response, dataList, "补贴申请");


    }


    @PostMapping("/export2")
    public void export2(SysSubsidyPlantingBo bo, HttpServletResponse response) throws IOException {
        List<SysSubsidyPlantingBo> dataList = iSysSubsidyPlantingService.queryList(bo);

        // 动态处理数据
        List<Map<String, Object>> processedData = new ArrayList<>();
        Map<String, String> conditionParams = new HashMap<>();
        conditionParams.put("excelTypeDidao", bo.getExcelTypeDidao());

        dataList.forEach(vo -> {
            Map<String, Object> map = DynamicExcelExporter.processToMap(vo, conditionParams);
            processedData.add(map);
        });

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("补贴申请", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 直接使用EasyExcel导出
        try (OutputStream os = response.getOutputStream()) {
            // 转换表头为List<List<String>>格式
            List<List<String>> headers = new ArrayList<>();
            if (!processedData.isEmpty()) {
                processedData.get(0).keySet().forEach(key -> {
                    List<String> headerRow = new ArrayList<>();
                    headerRow.add(key);
                    headers.add(headerRow);
                });
            }

            EasyExcel.write(os)
                .head(headers)
                .sheet("补贴申请")
                .doWrite(processedData);
        }
    }


    /**
     * 获取农业补贴申请详细信息
     *
     * @param id 主键
     */
    // @SaCheckPermission("subsidy:subsidyApplication:query")
    @GetMapping("/{id}")
    public R<SysSubsidyPlantingBo> getInfo(@NotNull(message = "主键不能为空")
                                           @PathVariable Long id) {
        return R.ok(iSysSubsidyPlantingService.queryById(id));
    }

     /**
     * 获取农业补贴申请详细信息
     *
     * @param
     */
    // @SaCheckPermission("subsidy:subsidyApplication:query")
    @GetMapping("/getCunCharge")
    public R<SysSubsidyPlantingBo> getCunCharge(SysSubsidyPlantingBo bo) {
        List<SysSubsidyPlantingBo> list = iSysSubsidyPlantingService.queryListChage(bo);
        SysSubsidyPlantingBo boo = new SysSubsidyPlantingBo();
        if (!list.isEmpty() && list.size()>0) {
            boo = list.get(0);
        }
        return R.ok(boo);
    }

    /**
     * 获取农业补贴申请详细信息
     *
     * @param
     */
    // @SaCheckPermission("subsidy:subsidyApplication:query")
    @GetMapping("/getAmountGroup")
    public List<SysSubsidyPlantingBo> getAmountGroup(SysSubsidyPlantingBo bo) {
        List<SysSubsidyPlantingBo> list=new ArrayList<>();
        if(StringUtils.isNotBlank(bo.getTownName())){
           list = iSysSubsidyPlantingService.getAmountGroupCun(bo);
        }
        if(StringUtils.isNotBlank(bo.getStraName())){
            list = iSysSubsidyPlantingService.getAmountGroupXi(bo);
        }
        SysPlantingPriceBo  pri=new SysPlantingPriceBo();
        pri.setYear(bo.getYear());
        List<SysPlantingPriceVo> listpri = iSysPlantingPriceService.queryList(pri);
        BigDecimal yumi = BigDecimal.ZERO;
        BigDecimal dadou = BigDecimal.ZERO;
        BigDecimal daogudixia = BigDecimal.ZERO;
        BigDecimal daogudibiao = BigDecimal.ZERO;
        BigDecimal gaodan = BigDecimal.ZERO;
        BigDecimal gaoyou = BigDecimal.ZERO;
        BigDecimal genlidili = BigDecimal.ZERO;
        BigDecimal gendilunzuo= BigDecimal.ZERO;
        for (SysPlantingPriceVo vo : listpri) {
            switch (vo.getType()) {
                case "玉米补贴":
                    yumi = new BigDecimal(vo.getPrice());
                    break;
                case "大豆补贴":
                    dadou = new BigDecimal(vo.getPrice());
                    break;
                case "稻谷地下水补贴":
                    daogudixia = new BigDecimal(vo.getPrice());
                    break;
                case "稻谷地表水补贴":
                    daogudibiao = new BigDecimal(vo.getPrice());
                    break;
                case "高蛋白大豆补贴":
                    gaodan = new BigDecimal(vo.getPrice());
                    break;
                case "高油大豆补贴":
                    gaoyou = new BigDecimal(vo.getPrice());
                    break;
                case "耕地地力补贴":
                    genlidili = new BigDecimal(vo.getPrice());
                    break;
                case "耕地轮作补贴":
                    gendilunzuo = new BigDecimal(vo.getPrice());
                    break;
                default:
                    // 其他类型不做处理
                    break;
            }
        }
        for (SysSubsidyPlantingBo e : list) {
            e.setYumiareaAmountPri(yumi.multiply(e.getYumiareaAmount()));
            e.setDadouareaAmountPri(dadou.multiply(e.getDadouareaAmount()));
           // e.setDaoguheareaAmountPri(daogu.multiply(e.getDaoguheareaAmount()));
            e.setDaogudibiareaAmountPri(daogudibiao.multiply(e.getDaogudibiareaAmount()));
            e.setDaogudixiaareaAmountPri(daogudixia.multiply(e.getDaogudixiaareaAmount()));
            e.setDaoguheareaAmountPri(e.getDaogudibiareaAmountPri().add(e.getDaogudixiaareaAmountPri()));
            e.setAreaAmountPri(e.getYumiareaAmountPri().add(e.getDadouareaAmountPri().add(e.getDaoguheareaAmountPri())));

            e.setAreaAmountdou(e.getAreaAmountdouGaoyou().add(e.getAreaAmountdouGaodanbai()));
            e.setAreaAmountdouGaoyouPri(gaoyou.multiply(e.getAreaAmountdouGaoyou()));
            e.setAreaAmountdouGaodanbaiPri(gaodan.multiply(e.getAreaAmountdouGaodanbai()));
            e.setAreaAmountdouPri(e.getAreaAmountdouGaoyouPri().add(e.getAreaAmountdouGaodanbaiPri()));
            e.setFarmlandareaAmountPri(genlidili.multiply(e.getFarmlandareaAmount()));
            e.setCurallonepre(gendilunzuo.multiply(e.getCurallone()));
            e.setCuralltwopre(gendilunzuo.multiply(e.getCuralltwo()));
            e.setCurallthreepre(gendilunzuo.multiply(e.getCurallthree()));
            e.setCurallfourpre(gendilunzuo.multiply(e.getCurallfour()));
            e.setCropallpre(gendilunzuo.multiply(e.getCropall()));
        }
        return list;
    }



    /**
     * 获取农业补贴申请详细信息
     *
     * @param bo 主键
     */
    // @SaCheckPermission("subsidy:subsidyApplication:query")
    @GetMapping("/selectOne")
    public R<SysSubsidyPlantingBo> getInfo(SysSubsidyPlantingBo bo) {
        return R.ok(iSysSubsidyPlantingService.queryByPlantingBo(bo));
    }

    /**
     * 新增补贴申请
     @SaCheckPermission("subsidy:subsidyApplication:add")
     @Log(title = "补贴申请", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping() public R<Void> add(@Validated(AddGroup.class) @RequestBody SysSubsidyPlantingBo bo) {
     return toAjax(iSysSubsidyPlantingService.insertByBo(bo));
     }
     */

    /**
     * 保存农业补贴
     */
    //  @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "保存农业补贴", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/submitnongye")
    public R<Object> submitnongye(@RequestBody SysSubsidyPlantingBo bo) {

        SysStrativeAreaBo boArea = new SysStrativeAreaBo();
        boArea.setVillageName(bo.getVillageName());
        List<SysStrativeAreaVo> areaVos = iSysStrativeAreaService.queryList(boArea);
        String townName = areaVos.stream().map(t -> t.getTownName()).findFirst().get();
        bo.setTownName(townName);
        bo.setStraName("滴道区");
        return R.ok((Object) iSysSubsidyPlantingService.insertByBo(bo));
    }

    /**
     * 一键提交接口
     */
    // @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "一键提交接口", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/submitAll")
    public R<Object> submitAll(@RequestBody SysSubsidyPlantingBo bo) {
        //SysSubsidyMachineBo boo = iSysSubsidyMachineService.queryById(bo.getId());
        LoginUser loginUser = LoginHelper.getLoginUser();
        String key = loginUser.getRoles().get(0).getRoleKey();
        bo.setIsprice("1");
        if ("district".equals(key)) {
            bo.setIsprice("2");
            bo.setNode(1);
            bo.setStatus("待处理");
            bo.setNodeName("滴道区");
            bo.setStraName("滴道区");
        }
        if ("town".equals(key)) {
            bo.setNode(3);
            bo.setStatus("审核中");
            bo.setNodeName("滴道区");
            bo.setTownName(loginUser.getTownName());
            SysPlantingTownttachBo tachBo = new SysPlantingTownttachBo();
            tachBo.setType(bo.getAppType());
            tachBo.setYear(bo.getYear());
            tachBo.setName(loginUser.getTownName());
            tachBo.setQingshifile(bo.getQingshifile());
            tachBo.setHechafile(bo.getHechafile());
            tachBo.setSaofile(bo.getSaofile());
            tachBo.setIsprice(bo.getIsprice());
            iSysPlantingTownttachService.insertByBo(tachBo);
        }
        if ("village".equals(key)) {
            bo.setNode(2);
            bo.setStatus("审核中");
            bo.setNodeName(loginUser.getTownName());
            bo.setVillageName(loginUser.getVillageName());
        }

     /*   String vili = bo.getVillageName();
        if (vili.contains("村")) {
            SysStrativeAreaBo boArea = new SysStrativeAreaBo();
            bo.setVillageName(vili);
            List<SysStrativeAreaVo> areaVos = iSysStrativeAreaService.queryList(boArea);
            String townName = areaVos.stream().map(t -> t.getTownName()).findFirst().get();
            //planbo.setYear(plan.getYear());
            // planbo.setVillageName(plan);
            bo.setNode(2);
            bo.setNodeName(townName);
            bo.setProccResult("正常");
            bo.setStatus("已处理");*/
        Boolean bo1 = iSysSubsidyPlantingService.updateByPlanBo(bo);
        //System.out.println("ff");
        return R.ok();
    }

    /**
     * 一键提交接口
     */
    // @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "一键处理补贴发放", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/submitPriceAll")
    public R<Object> submitPriceAll(@RequestBody SysSubsidyPlantingBo bo) {
        //SysSubsidyMachineBo boo = iSysSubsidyMachineService.queryById(bo.getId());
        LoginUser loginUser = LoginHelper.getLoginUser();
        String key = loginUser.getRoles().get(0).getRoleKey();
        bo.setIsprice("2");
        if ("district".equals(key)) {
            bo.setNode(3);
            bo.setStatus("已完成");
            bo.setNodeName("滴道区");
            bo.setStraName("滴道区");
        }
        if ("town".equals(key)) {
            bo.setNode(3);
            bo.setStatus("审核中");
            bo.setNodeName("滴道区");
            bo.setTownName(loginUser.getTownName());
            SysPlantingTownttachBo tachBo = new SysPlantingTownttachBo();
            tachBo.setType(bo.getAppType());
            tachBo.setYear(bo.getYear());
            tachBo.setName(loginUser.getTownName());
            tachBo.setQingshifile(bo.getQingshifile());
            tachBo.setHechafile(bo.getHechafile());
            tachBo.setSaofile(bo.getSaofile());
            tachBo.setIsprice(bo.getIsprice());
            iSysPlantingTownttachService.insertByBo(tachBo);
        }
        if ("village".equals(key)) {
            bo.setNode(2);
            bo.setStatus("审核中");
            bo.setNodeName(loginUser.getTownName());
            bo.setVillageName(loginUser.getVillageName());
        }

     /*   String vili = bo.getVillageName();
        if (vili.contains("村")) {
            SysStrativeAreaBo boArea = new SysStrativeAreaBo();
            bo.setVillageName(vili);
            List<SysStrativeAreaVo> areaVos = iSysStrativeAreaService.queryList(boArea);
            String townName = areaVos.stream().map(t -> t.getTownName()).findFirst().get();
            //planbo.setYear(plan.getYear());
            // planbo.setVillageName(plan);
            bo.setNode(2);
            bo.setNodeName(townName);
            bo.setProccResult("正常");
            bo.setStatus("已处理");*/
        Boolean bo1 = iSysSubsidyPlantingService.updateByPlanBo(bo);
        //System.out.println("ff");
        return R.ok();
    }


    /**
     * 一键驳回接口
     */
    // @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "一键驳回接口", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/rejectAll")
    public R<Object> RejectAll(@RequestBody SysSubsidyPlantingBo bo) {
       /* String vili = bo.getVillageName();
        if (vili.contains("村")) {
            bo.setNode(1);
            bo.setNodeName(vili);
            // plan.setProccResult("驳回");
            bo.setStatus("已处理");
            Boolean bo1 = iSysSubsidyPlantingService.updateByPlanBo(bo);
        }*/
        LoginUser loginUser = LoginHelper.getLoginUser();
        String key = loginUser.getRoles().get(0).getRoleKey();
        bo.setIsprice("1");
        //bo.setStatus("待处理");
        if ("district".equals(key)) {
            bo.setNode(2);
            // bo.setStatus("待发放");
            bo.setNodeName(bo.getTownName());
            bo.setStraName("滴道区");
            SysPlantingTownttachBo tachBo = new SysPlantingTownttachBo();
            tachBo.setType(bo.getAppType());
            tachBo.setYear(bo.getYear());
            tachBo.setName(bo.getTownName());
            // tachBo.setQingshifile(bo.getQingshifile());
            //  tachBo.setHechafile(bo.getHechafile());
            // tachBo.setSaofile(bo.getSaofile());
            tachBo.setReject(bo.getAbnormal());
            tachBo.setRejectflag("1");
            tachBo.setIsprice(bo.getIsprice());
            iSysPlantingTownttachService.insertByBo(tachBo);
        }
        Boolean bo1 = iSysSubsidyPlantingService.updateByPlanBoBohui(bo);
        return R.ok();
    }

    /**
     * 单个驳回接口
     */
    // @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "单个驳回接口", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/rejectOne")
    public R<Object> RejectOne(@RequestBody SysSubsidyPlantingBo bo) {
        bo.setProccResult("驳回");
        bo.setStatus("异常");
        Boolean bo1 = iSysSubsidyPlantingService.updateByPlanBoOne(bo);
        return R.ok();
    }

    /**
     * 单个驳回接口
     */
    // @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "批量驳回接口", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/rejectOneBatch")
    public R<Object> rejectOneBatch(@RequestBody List<SysSubsidyPlantingBo> boList) {
      /*  bo.setProccResult("驳回");
        bo.setStatus("异常");
        Boolean bo1 = iSysSubsidyPlantingService.updateByPlanBoOne(bo);
        return R.ok(); */
        // 验证appNum唯一性
        Set<String> appNums = new HashSet<>();
        for (SysSubsidyPlantingBo bo : boList) {
            if (StringUtils.isEmpty(bo.getAppNum())) {
                return R.fail("appNum不能为空");
            }
            if (!appNums.add(bo.getAppNum())) {
                return R.fail("存在重复的appNum: " + bo.getAppNum());
            }
        }

        // 批量处理逻辑
        for (SysSubsidyPlantingBo bo : boList) {
            bo.setProccResult("驳回");
            bo.setStatus("异常");
            if (!iSysSubsidyPlantingService.updateByPlanBoOne(bo)) {
                return R.fail("部分数据更新失败");
            }
        }

        return R.ok("批量驳回成功");
    }



    /**
     * 单个审核通过接口
     */
    // @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "单个审核通过接口", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/approveOne")
    public R<Object> approveOne(@RequestBody SysSubsidyPlantingBo bo) {
        bo.setProccResult("正常");
        bo.setStatus("已处理");
        Boolean bo1 = iSysSubsidyPlantingService.updateByPlanBoOne(bo);
        return R.ok();
    }

    /**
     * 单个审核通过接口
     */
    // @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "批量审核通过接口", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/approveOneBatch")
    public R<Object> approveOneBatch(@RequestBody List<SysSubsidyPlantingBo> boList) {
       /* bo.setProccResult("正常");
        bo.setStatus("已处理");
        Boolean bo1 = iSysSubsidyPlantingService.updateByPlanBoOne(bo);
        return R.ok();*/

        Set<String> appNums = new HashSet<>();
        for (SysSubsidyPlantingBo bo : boList) {
            if (StringUtils.isEmpty(bo.getAppNum())) {
                return R.fail("appNum不能为空");
            }
            if (!appNums.add(bo.getAppNum())) {
                return R.fail("存在重复的appNum: " + bo.getAppNum());
            }
        }

        // 批量处理逻辑
        for (SysSubsidyPlantingBo bo : boList) {
            bo.setProccResult("正常");
            bo.setStatus("已处理");
            if (!iSysSubsidyPlantingService.updateByPlanBoOne(bo)) {
                return R.fail("部分数据更新失败");
            }
        }

        return R.ok("批量审核成功");
    }



    /**palan
     * 申请农业补贴

     @SaCheckPermission("subsidy:subsidyApplication:add")
     @Log(title = "申请农业补贴", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping("/submitnongye") public R<Object> submitnongji( @RequestBody SysSubsidyPlantingBo bo) {
     return R.ok((Object)iSysSubsidyPlantingService.insertByBo(bo));
     }
     */


    /**
     * 修改农业补贴申请
     */
    // @SaCheckPermission("subsidy:subsidyApplication:edit")
    @Log(title = "补贴申请", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysSubsidyPlantingBo bo) {
        return toAjax(iSysSubsidyPlantingService.updateByBo(bo));
    }

    /**
     * 删除农业补贴申请
     *
     * @param ids 主键串
     */
    //  @SaCheckPermission("subsidy:subsidyApplication:remove")
    @Log(title = "补贴申请", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(iSysSubsidyPlantingService.deleteWithValidByIds(Arrays.asList(ids), true));
    }


    /**
     * ocr识别
     */
    //  @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "ocr识别", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/ocrshi")
    public ResponseEntity<Object> ocrshi(@RequestParam("materialId") MultipartFile file) {
        RestTemplate restTemplate = new RestTemplate();
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        //headers.setContentType(MediaType.APPLICATION_JSON); // 标准方式
        headers.set("hsPartyId", "hl230300");  // 系统参数
        // headers.set("Authorization", "Bearer " + "b94e5cfc-f580-4de4-8187-4835f91d4d9e"); // 添加Token头
        LinkedHashMap<String, String> sorted = new LinkedHashMap<>();
        // 构建请求体
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("materialId", file.getResource());
        // 构建完整请求URL（包含查询参数）
        String fullUrl = apiUrlneiwang + "?" + getQueryUrl(sorted);
        // 创建请求实体
        try {
            HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
            // ResponseEntity<Object> response = restTemplate.postForEntity(fullUrl, entity, Object.class);
            ResponseEntity<String> response = restTemplate.exchange(fullUrl,
                HttpMethod.POST,
                entity,
                String.class
            );
            return ResponseEntity.ok(response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("OCR识别接口调用失败: " + e.getMessage());
        }
    }

    /**
     * 短信接口
     */
    //  @SaCheckPermission("subsidy:subsidyApplication:add")
    @Log(title = "短信接口", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/sendMs")
    public ResponseEntity<Object> sendMs() {
        RestTemplate restTemplate = new RestTemplate();
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("hsPartyId", "hl230300");  // 系统参数
        headers.set("accessToken", "e02cc607-c475-44b5-aa2b-45371583c454");
        //headers.set("Authorization", "Bearer " + "0c4f9037-b9a8-4b52-a4f3-72c06dca8859"); // 添加Token头
        LinkedHashMap<String, String> sorted = new LinkedHashMap<>();
        // 构建请求体
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        //body.add("materialId", file.getResource());
        body.add("appUuid", "1234");
        body.add("appMark", "12345");
        body.add("appSecret", "97ac3144d326302dde649625d510b0d7");
        Map<String, String> data = new HashMap<>();
        data.put("userMobile", "13048734127");
        body.add("data", data);
        // 构建完整请求URL（包含查询参数）
        String fullUrl = apiUrlms + "?" + getQueryUrl(sorted);
        // 创建请求实体
        try {
            HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
            // ResponseEntity<Object> response = restTemplate.postForEntity(fullUrl, entity, Object.class);
            ResponseEntity<String> response = restTemplate.exchange(fullUrl,
                HttpMethod.POST,
                entity,
                String.class
            );
            return ResponseEntity.ok(response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("OCR识别接口调用失败: " + e.getMessage());
        }
    }


    //构建查询参数字符串
    private String buildQueryString(MultiValueMap<String, String> params) {
        StringBuilder sb = new StringBuilder();
        params.forEach((key, values) -> {
            values.forEach(value -> {
                if (sb.length() > 0) {
                    sb.append("&");
                }
                sb.append(key).append("=").append(value);
            });
        });
        return sb.toString();
    }

    /**
     * 获得query参数，没有传空集合
     *
     * @param params
     * @return
     */

    public String getQueryUrl(LinkedHashMap<String, String> params) {
        Map<String, String> sorted = new LinkedHashMap<>();
        if (null != params && params.size() > 0) {
            params.forEach((k, v) -> sorted.put(k, v));
        }
        sorted.put("AccessKey", AppKey);
        sorted.put("SecretKey", AppSecret);
        sorted.put("timestamp", String.valueOf(System.currentTimeMillis()));
        sorted.put("nonce", String.valueOf(new Random().nextInt()));
        sorted.put("sign", getSign(sorted));
        sorted.remove("SecretKey");
        StringBuilder builder = new StringBuilder();
        sorted.forEach((k, v) -> {
            try {
                builder.append(k).append("=").append(URLEncoder.encode(v, "utf-8")).append("&");
            } catch (UnsupportedEncodingException e) {

                System.out.println("对参数进行重新编码时出错。");
            }
        });
        builder.deleteCharAt(builder.length() - 1);
        return builder.toString();
    }

    //计算sign
    public String getSign(Map<String, String> params) {
        Map<String, String> sorted = new TreeMap<>();
        params.forEach((k, v) -> sorted.put(k, v));
        StringBuilder builder = new StringBuilder();
        sorted.forEach((k, v) -> {
            builder.append(k).append("=").append(v).append("&");

        });
        String value = builder.toString();
        value = value.substring(0, value.length() - 1);
        return DigestUtils.md5DigestAsHex(value.getBytes()).toUpperCase();
    }

    @PostMapping("/applySeal")
    public R<Object> applySeal(
        @RequestParam("file") MultipartFile file,@RequestParam("signArea") String signArea) throws IOException, ParserConfigurationException, SAXException {
        // 1. 读取文件并转为Base64
        byte[] fileBytes = file.getBytes();
        String base64File = Base64.getEncoder().encodeToString(fileBytes);
        RestTemplate restTemplate = new RestTemplate();
        //FileInputStream in=new FileInputStream();

        // 2. 构建请求体
        SealRequest request = new SealRequest();
        InetAddress localHost = InetAddress.getLocalHost();
        String ipAddress = localHost.getHostAddress();
        String sysId = "jxnpt";
        String sysPwd = "jxnpt";
        String userDepart = "研发部";
        String userName = "农补通";
        String keyWord = "需要盖章";
        String macAddress = "255.255.255.0";
        LoginUser loginUser = LoginHelper.getLoginUser();
        String signNum = loginUser.getSignNum();
        if(StringUtils.isEmpty(signNum)){
            SysOssVo ossOld = iSysOssService.upload(file);
            return  R.ok(ossOld.getUrl());
        }
        request.setBaseData(new BaseData(sysId, sysPwd, userDepart, userName, ipAddress, macAddress));
        request.setMetaData(new MetaData("false"));
        RuleNode roleNode = new RuleNode("0,39000,5,5,40000,", signNum);
        RuleNode roleNode1 = new RuleNode("1,39000,5,5,7500,", signNum);

        List<RuleNode> list=new ArrayList<>();
        list.add(roleNode);
        if("2".equals(signArea)) {
            list.add(roleNode1);
        }
        RuleNodeList ruleNodeList = new RuleNodeList();
        ruleNodeList.setList(list);

        FileNode fileNode = new FileNode(
            file.getOriginalFilename(),
            file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')),
            "BASE64",
            base64File,
            "false",
            "false",
            "pdf",
            "1",
            "230300",
            ruleNodeList,
            "BASE64");
        TreeNode treeNode = new TreeNode(fileNode);
        request.setTreeNode(treeNode);
        HttpHeaders headers = new HttpHeaders();
        headers.set("hsPartyId", "hl230300");  // 系统参数
        headers.setContentType(MediaType.APPLICATION_XML);
        HttpEntity<SealRequest> entity = new HttpEntity<>(request, headers);
        //restTemplate
        LinkedHashMap<String, String> sorted = new LinkedHashMap<>();
        String fullUrl = apiUrlyin + "?" + getQueryUrl(sorted);
        // 2. 序列化为XML并打印调试
        String requestXml = xmlMapper.writeValueAsString(request);
        logger.info("Generated Request XML:\n{}", requestXml);

        ResponseEntity<String> response = restTemplate.exchange(fullUrl,
            HttpMethod.POST,
            entity,
            String.class
        );
        // 3. 解析XML响应
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(response.getBody())));

        NodeList fileDataNodes = doc.getElementsByTagName("FILE_DATA");
        if (fileDataNodes.getLength() == 0) {
            throw new RuntimeException("No file data in response");
        }

        String base64Data = fileDataNodes.item(0).getTextContent();
        byte[] fileBytess = Base64.getDecoder().decode(base64Data);
        // 4. 获取文件名
        NodeList fileNoNodes = doc.getElementsByTagName("FILE_NO");
        String fileName = fileNoNodes.getLength() > 0 ?
            fileNoNodes.item(0).getTextContent() : "sealed_file.pdf";
        MultipartFile file1=base64ToMultipart(base64Data,fileName);

        SysOssVo oss = iSysOssService.upload(file1);
        return  R.ok(oss.getUrl());
        // 5. 返回文件
       /* return ResponseEntity.ok()
            .header("Content-Disposition", "attachment; filename=\"" + fileName + "\"")
            .body(fileBytess); */
    }
        /*restTemplate.postForEntity(
            fullUrl,
            entity,
            SealResponse.class)*/;
    //return null;
    // 4. 处理响应
        /*if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
            String base64Result = response.getBody().getFileList().get(0).getFileData();
            return ResponseEntity.ok()
                .header("Content-Disposition", "attachment; filename=" + response.getBody().getFileList().get(0).getFileNo())
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(Base64.getDecoder().decode(base64Result));
        } else {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
         */



    public static MultipartFile base64ToMultipart(String base64Data, String fileName) throws IOException {
        // 移除可能的Base64前缀（如"data:image/png;base64,"）
        String pureBase64 = base64Data.split(",").length > 1 ?
            base64Data.split(",")[1] : base64Data;

        byte[] fileBytes = Base64.getDecoder().decode(pureBase64);

        // 获取文件扩展名（从文件名或默认）
        String extension = fileName.contains(".") ?
            fileName.substring(fileName.lastIndexOf(".") + 1) : "bin";

        return new MockMultipartFile(
            "file",
            fileName,
            "application/octet-stream",
            fileBytes
        );
    }

    @PostMapping("/applySealNew")
    public ResponseEntity<byte[]> applySealNew(
            @RequestParam("file") MultipartFile file,@RequestParam("signArea") String signArea) throws IOException, ParserConfigurationException, SAXException {
        // 1. 读取文件并转为Base64
        byte[] fileBytes = file.getBytes();
        String base64File = Base64.getEncoder().encodeToString(fileBytes);
        RestTemplate restTemplate = new RestTemplate();
        //FileInputStream in=new FileInputStream();


        // 2. 构建请求体
        SealRequest request = new SealRequest();
        InetAddress localHost = InetAddress.getLocalHost();
        String ipAddress = localHost.getHostAddress();
        String sysId = "jxnpt";
        String sysPwd = "jxnpt";
        String userDepart = "研发部";
        String userName = "农补通";
        String keyWord = "需要盖章";
        String macAddress = "255.255.255.0";
        LoginUser loginUser = LoginHelper.getLoginUser();
        String signNum = loginUser.getSignNum();
        request.setBaseData(new BaseData(sysId, sysPwd, userDepart, userName, ipAddress, macAddress));
        request.setMetaData(new MetaData("false"));
        RuleNode roleNode = new RuleNode("0,39000,5,5,40000,", signNum);
        RuleNode roleNode1 = new RuleNode("1,39000,5,5,7500,", signNum);
        RuleNodeNew ruleNodeNew = new RuleNodeNew(roleNode);

        List<RuleNode> list=new ArrayList<>();
        list.add(roleNode);
        list.add(roleNode1);
        RuleNodeList ruleNodeList = new RuleNodeList();
        ruleNodeList.setList(list);

        FileNode fileNode = new FileNode(
            file.getOriginalFilename(),
            file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')),
            "BASE64",
            base64File,
            "false",
            "false",
            "pdf",
            "1",
            "230300",
            ruleNodeList,
            "BASE64");
        TreeNode treeNode = new TreeNode(fileNode);
        request.setTreeNode(treeNode);
        HttpHeaders headers = new HttpHeaders();
        headers.set("hsPartyId", "hl230300");  // 系统参数
        headers.setContentType(MediaType.APPLICATION_XML);
        HttpEntity<SealRequest> entity = new HttpEntity<>(request, headers);
        //restTemplate
        LinkedHashMap<String, String> sorted = new LinkedHashMap<>();
        String fullUrl = apiUrlyin + "?" + getQueryUrl(sorted);
        // 2. 序列化为XML并打印调试
        String requestXml = xmlMapper.writeValueAsString(request);
        logger.info("Generated Request XML:\n{}", requestXml);

        ResponseEntity<String> response = restTemplate.exchange(fullUrl,
            HttpMethod.POST,
            entity,
            String.class
        );
        // 3. 解析XML响应
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(response.getBody())));

        NodeList fileDataNodes = doc.getElementsByTagName("FILE_DATA");
        if (fileDataNodes.getLength() == 0) {
            throw new RuntimeException("No file data in response");
        }

        String base64Data = fileDataNodes.item(0).getTextContent();
        byte[] fileBytess = Base64.getDecoder().decode(base64Data);

        // 4. 获取文件名
        NodeList fileNoNodes = doc.getElementsByTagName("FILE_NO");
        String fileName = fileNoNodes.getLength() > 0 ?
            fileNoNodes.item(0).getTextContent() : "sealed_file.pdf";
        // 5. 返回文件
        return ResponseEntity.ok()
            .header("Content-Disposition", "attachment; filename=\"" + fileName + "\"")
            .body(fileBytess);
    }
}
